<script lang="ts" setup>
import {onMounted, reactive, ref} from 'vue'
import {useRouter} from 'vue-router'
import type {UploadProps} from 'ant-design-vue'
import {CheckCircleOutlined, DeleteOutlined, PictureOutlined, UploadOutlined} from '@ant-design/icons-vue'
import MainLayout from '@/components/layout/MainLayout.vue'
import {pictureApi, spaceApi} from '@/api'
import type {PictureUploadDTO} from '@/types/dto/picture'
import type {SpaceVO} from '@/types/vo/space'
import {PICTURE_CATEGORIES} from '@/constants/picture'
import {error, handleError, success, warning} from '@/utils/message'
import {FormRules, validate} from '@/utils/validate'
import {UPLOAD} from '@/constants/messages'

const router = useRouter()

const uploading = ref(false)
const fileList = ref<any[]>([])
const previewUrl = ref('')
const mySpaces = ref<SpaceVO[]>([])
const currentFile = ref<File | null>(null) // 保存当前选择的文件

const formState = reactive<PictureUploadDTO>({
  pictureName: '',
  introduction: '',
  spaceId: undefined,
  category: undefined,
  tags: []
})

const rules = {
  pictureName: FormRules.pictureName,
  introduction: FormRules.introduction
}

// 上传前检查
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    error(UPLOAD.INVALID_FILE_TYPE)
    return false
  }

  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    error(UPLOAD.FILE_TOO_LARGE)
    return false
  }

  return false // 阻止自动上传
}

// 文件变化处理
const handleFileChange: UploadProps['onChange'] = (info) => {
  const {file} = info

  if (file.status === 'removed') {
    previewUrl.value = ''
    currentFile.value = null
    fileList.value = []
    return
  }

  // 获取原始文件
  const originFile = (file.originFileObj || file) as unknown as File

  if (originFile) {
    // 保存文件引用
    currentFile.value = originFile
    // 手动更新 fileList
    fileList.value = [file]

    // 生成预览
    const reader = new FileReader()
    reader.onload = (e) => {
      previewUrl.value = e.target?.result as string
    }
    reader.readAsDataURL(originFile)

    // 如果没有填写图片名称，使用文件名
    if (!formState.pictureName) {
      const fileName = originFile.name || ''
      formState.pictureName = fileName.replace(/\.[^/.]+$/, '')
    }
  }
}

// 移除文件
const handleRemove = () => {
  previewUrl.value = ''
  currentFile.value = null
  fileList.value = []
}

// 提交上传
const handleSubmit = async () => {
  if (!currentFile.value) {
    warning(UPLOAD.FILE_REQUIRED)
    return
  }

  // 验证必填字段
  if (!validate.required(formState.pictureName)) {
    warning('请输入图片名称')
    return
  }

  uploading.value = true
  try {
    const file = currentFile.value

    // 创建FormData
    const formData = new FormData()
    formData.append('file', file)

    if (formState.spaceId) {
      formData.append('spaceId', formState.spaceId.toString())
    }
    if (formState.pictureName && formState.pictureName.trim()) {
      formData.append('pictureName', formState.pictureName.trim())
    }
    if (formState.introduction && formState.introduction.trim()) {
      formData.append('introduction', formState.introduction.trim())
    }
    if (formState.category) {
      formData.append('category', formState.category)
    }
    if (formState.tags && formState.tags.length > 0) {
      formData.append('tags', formState.tags.join(','))
    }

    const result = await pictureApi.upload(formData)
    success(UPLOAD.SUCCESS)

    // 清空表单
    handleReset()

    // 延迟跳转，让用户看到成功提示
    setTimeout(() => {
      router.push(`/picture/${result.id}`)
    }, 500)
  } catch (error: any) {
    handleError(error, UPLOAD.FAILED)
  } finally {
    uploading.value = false
  }
}

// 重置表单
const handleReset = () => {
  fileList.value = []
  currentFile.value = null
  previewUrl.value = ''
  formState.pictureName = ''
  formState.introduction = ''
  formState.spaceId = undefined
  formState.category = undefined
  formState.tags = []
}

// 加载我的空间列表
const loadMySpaces = async () => {
  try {
    const result = await spaceApi.getMySpaces()
    mySpaces.value = [...result.owner, ...result.joined]
  } catch (error: any) {
    // 静默失败，不影响主流程
  }
}

onMounted(() => {
  loadMySpaces()
})
</script>

<template>
  <main-layout>
    <div class="upload-container">
      <a-card :bordered="false" title="上传图片">
        <a-form
            :label-col="{ span: 4 }"
            :model="formState"
            :rules="rules"
            :wrapper-col="{ span: 16 }"
            @finish="handleSubmit"
        >
          <!-- 文件上传 -->
          <a-form-item label="选择图片" required>
            <!-- 优化后的上传区域 -->
            <div v-if="!previewUrl" class="upload-area">
              <a-upload
                  v-model:file-list="fileList"
                  :before-upload="beforeUpload"
                  :max-count="1"
                  :show-upload-list="false"
                  accept="image/*"
                  @change="handleFileChange"
              >
                <div class="upload-button-area">
                  <div class="upload-icon">
                    <PictureOutlined/>
                  </div>
                  <div class="upload-text">
                    <p class="upload-main-text">点击选择图片</p>
                    <p class="upload-hint-text">或拖拽图片到此处</p>
                  </div>
                </div>
              </a-upload>
              <div class="upload-tips">
                <p>支持 JPG、PNG、GIF、WEBP 格式</p>
                <p>单个文件不超过 10MB</p>
              </div>
            </div>

            <!-- 图片预览 -->
            <div v-else class="preview-area">
              <div class="preview-image">
                <img :src="previewUrl" alt="预览图"/>
                <div class="preview-mask">
                  <a-button danger size="small" type="primary" @click="handleRemove">
                    <template #icon>
                      <DeleteOutlined/>
                    </template>
                    移除图片
                  </a-button>
                </div>
              </div>
              <div class="preview-info">
                <CheckCircleOutlined style="color: #52c41a; font-size: 20px;"/>
                <span>图片已选择，填写信息后点击上传</span>
              </div>
            </div>
          </a-form-item>

          <!-- 图片名称 -->
          <a-form-item label="图片名称" name="pictureName" required>
            <a-input
                v-model:value="formState.pictureName"
                :maxlength="100"
                placeholder="请输入图片名称（必填）"
                show-count
            />
          </a-form-item>

          <!-- 图片简介 -->
          <a-form-item label="图片简介" name="introduction">
            <a-textarea
                v-model:value="formState.introduction"
                :maxlength="500"
                :rows="4"
                placeholder="请输入图片简介"
                show-count
            />
          </a-form-item>

          <!-- 所属空间 -->
          <a-form-item label="所属空间" name="spaceId">
            <a-select
                v-model:value="formState.spaceId"
                allowClear
                placeholder="选择空间（可选）"
            >
              <a-select-option :value="null">公共空间</a-select-option>
              <a-select-option
                  v-for="space in mySpaces"
                  :key="space.id"
                  :value="space.id"
              >
                {{ space.spaceName }}
              </a-select-option>
            </a-select>
          </a-form-item>

          <!-- 分类 -->
          <a-form-item label="分类" name="category">
            <a-select
                v-model:value="formState.category"
                allowClear
                placeholder="选择分类（可选）"
            >
              <a-select-option
                  v-for="cat in PICTURE_CATEGORIES"
                  :key="cat.value"
                  :value="cat.value"
              >
                {{ cat.label }}
              </a-select-option>
            </a-select>
          </a-form-item>

          <!-- 标签 -->
          <a-form-item label="标签" name="tags">
            <a-select
                v-model:value="formState.tags"
                :max-tag-count="5"
                mode="tags"
                placeholder="输入标签后按回车"
            />
          </a-form-item>

          <!-- 提交按钮 -->
          <a-form-item :wrapper-col="{ offset: 4, span: 16 }">
            <a-space>
              <a-button :loading="uploading" html-type="submit" size="large" type="primary">
                <template #icon>
                  <UploadOutlined/>
                </template>
                {{ uploading ? '上传中...' : '立即上传' }}
              </a-button>
              <a-button size="large" @click="handleReset">重置</a-button>
            </a-space>
          </a-form-item>
        </a-form>
      </a-card>
    </div>
  </main-layout>
</template>

<style lang="scss" scoped>
.upload-container {
  max-width: 900px;
  margin: 24px auto;
  padding: 0 24px;
}

.upload-area {
  .upload-button-area {
    border: 2px dashed #d9d9d9;
    border-radius: 12px;
    padding: 40px 20px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s;
    background: #fafafa;

    &:hover {
      border-color: #1890ff;
      background: #f0f7ff;

      .upload-icon {
        color: #1890ff;
        transform: scale(1.1);
      }
    }

    .upload-icon {
      font-size: 64px;
      color: #999;
      margin-bottom: 16px;
      transition: all 0.3s;
    }

    .upload-text {
      .upload-main-text {
        font-size: 16px;
        font-weight: 500;
        color: #333;
        margin-bottom: 8px;
      }

      .upload-hint-text {
        font-size: 14px;
        color: #999;
        margin: 0;
      }
    }
  }

  .upload-tips {
    margin-top: 16px;
    padding: 12px 16px;
    background: #f5f5f5;
    border-radius: 8px;
    text-align: center;

    p {
      margin: 4px 0;
      font-size: 13px;
      color: #666;
    }
  }
}

.preview-area {
  .preview-image {
    position: relative;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);

    img {
      width: 100%;
      max-height: 400px;
      object-fit: contain;
      display: block;
      background: #f5f5f5;
    }

    .preview-mask {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0, 0, 0, 0.5);
      display: flex;
      align-items: center;
      justify-content: center;
      opacity: 0;
      transition: opacity 0.3s;

      &:hover {
        opacity: 1;
      }
    }
  }

  .preview-info {
    margin-top: 16px;
    padding: 12px 16px;
    background: #f6ffed;
    border: 1px solid #b7eb8f;
    border-radius: 8px;
    display: flex;
    align-items: center;
    gap: 12px;

    span {
      font-size: 14px;
      color: #52c41a;
      font-weight: 500;
    }
  }
}
</style>